package com.wh.usercenter3.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.wh.usercenter3.constant.CodeConstant;
import com.wh.usercenter3.exception.BaseException;
import com.wh.usercenter3.pojo.User;
import com.wh.usercenter3.pojo.vo.NewUserVo;
import com.wh.usercenter3.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 定时任务类
 */
@Component
@Slf4j
public class CronJob {
    @Resource
    private UserService userService;

    @Resource
    private RedisTemplate<String,Object> redisTemplate;

    @Resource
    private RedissonClient redissonClient;

    /**
     *  定时任务 缓存预热关键用户首页
     */
    @Scheduled(cron = "0 27 20 * * ?")
    public void userSetRedis() {
        log.info("定时任务：预热关键用户");
        // 创建一个redisson锁
        RLock lock = redissonClient.getLock("wh;userCenter3;userSetRedis;lock");

        try {
            // 抢锁（参数1：等待时间超过5s则返回false，参数2：开启看门狗自动续费延迟时间）
            if (lock.tryLock(50000, -1, TimeUnit.MILLISECONDS)) {
                String redisKey = String.format("wh;userCenter3;userPageQuery;%s;%s", 1,1);
                // 查数据库
                QueryWrapper<User> queryWrapper = new QueryWrapper<>();
                Page<User> userPage = userService.page(new Page<>(1, 10), queryWrapper);
                List<User> userList = userPage.getRecords();
                // 数据脱敏
                List<NewUserVo> newUserVos = userList.stream()
                        .map(user -> {
                            NewUserVo newUserVo = new NewUserVo();
                            BeanUtils.copyProperties(user, newUserVo);
                            return newUserVo;
                        })
                        .collect(Collectors.toList());
                // 写入缓存
                try {
                    redisTemplate.opsForValue().set(redisKey,newUserVos,10000, TimeUnit.MINUTES);
                } catch (Exception e) {
                    throw new BaseException(CodeConstant.SERVICE_ERR,"无法存入redis缓存");
                }

            }

        } catch (BaseException | InterruptedException e) {
            throw new BaseException(CodeConstant.SERVICE_ERR,"定时任务出错");
        }finally {
            // 放锁
            lock.unlock();
        }
    }
}
